package com.imooc.utils;

import com.imooc.exception.GraceException;
import com.imooc.result.ResponseStatusEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;

import javax.crypto.SecretKey;
import java.util.Date;

/**
 * @author liansen
 * @create 01-09-18:30
 */
@Component
@Slf4j
@RefreshScope
public class JwtUtils {

    @Autowired
    private JwtProperties jwtProperties;

    public static final String at = "@";

    @Value("${jwt.key}")
    public String JWT_KEY;


    public String createJWTWithPrefix(String body, String prefix){
        return prefix + at + createJWT(body);
    }

    public String createJWTWithPrefix(String body, Long expireTimes, String prefix){
        return prefix + at + createJWT(body, expireTimes);
    }

    public String createJWT(String body){
        return dealJWT(body, null);
    }

    public String createJWT(String body, Long expireTimes){
        if(expireTimes == null){
            GraceException.display(ResponseStatusEnum.SYSTEM_NO_EXPIRE_ERROR); //系统错误，缺少过期时间
        }
        return dealJWT(body, expireTimes);
    }

    public String dealJWT(String body, Long expireTimes){
        log.info("JWT_KEY:" + JWT_KEY);
        //对密钥进行base64编码
//        String encode = new BASE64Encoder().encode(jwtProperties.getKey().getBytes());
        String encode = new BASE64Encoder().encode(JWT_KEY.getBytes());
        //编码后生成一个密钥对象,自动选择加密算法 默认应该是HS256
        SecretKey secretKey = Keys.hmacShaKeyFor(encode.getBytes());
        String jwtToken = "";
        if(expireTimes != null){
            jwtToken = generatorJWT(body, expireTimes, secretKey);
        }else {
            jwtToken = generatorJWT(body, secretKey);
        }
        return jwtToken;
    }


    public String generatorJWT(String body, SecretKey secretKey){
        return Jwts.builder()
                .setSubject(body) //用户自定义数据
                .signWith(secretKey) ////使用哪个密钥对象进行token的生成
                .compact();
    }

    public String generatorJWT(String body, Long expireTimes, SecretKey secretKey){
        Date expireDate = new Date(System.currentTimeMillis() + expireTimes);
        return Jwts.builder()
                .setSubject(body) //用户自定义数据
                .setExpiration(expireDate) //设置token过期时间
                .signWith(secretKey) ////使用哪个密钥对象进行token的生成
                .compact();
    }

    //解jwt token
    public String checkJwtToken(String token){

        //对密钥进行base64编码
//        String encode = new BASE64Encoder().encode(jwtProperties.getKey().getBytes());
        String encode = new BASE64Encoder().encode(JWT_KEY.getBytes());

        //编码后生成一个密钥对象, 自动选择加密算法
        SecretKey secretKey = Keys.hmacShaKeyFor(encode.getBytes());

        //校验token
        //构建jwt token解析器
        JwtParser jwtParser = Jwts.parserBuilder().setSigningKey(secretKey).build();
        //解析token
        Jws<Claims> claimsJws = jwtParser.parseClaimsJws(token);
        //获取主体
        String subject = claimsJws.getBody().getSubject();
        return subject;

    }
}
